<template>
  <div :class="`tab-header`" @mousedown="clearEdit">
    <div class="content">
      <div class="content__left">
        <Tabs tabPosition="left" v-model:activeKey="activeKey" @change="getData">
          <template v-for="item0 in achieveList" :key="item0.key">
            <TabPane>
              <template #tab>
                <span>
                  <component
                    :is="item0.iconRender"
                    style="color: black; width: 45px; margin-right: 0px"
                  />
                  <span v-if="item0.bold" style="font-weight: 600">{{ item0.name }}</span>
                  <span v-else>{{ item0.name }}</span>
                </span>
              </template>
            </TabPane>
          </template>
        </Tabs>
      </div>
      <div class="content__right" @contextmenu="backgroudHandleContext">
        <div style="display: inline">
          <div>
            <!-- 按钮组 -->
            <div style="float: left; margin-bottom: 8px">
              <div
                v-for="btItem in buttonList"
                :key="btItem.key"
                style="display: inline-block; margin-right: 5px"
              >
                <a-upload
                  :customRequest="customRequest"
                  :showUploadList="false"
                  v-if="btItem.name === '上传'"
                >
                  <a-button type="primary" shape="round" style="margin-right: 3px">
                    <component :is="btItem.iconRender" />
                    {{ btItem.name }}
                  </a-button>
                </a-upload>
                <a-button
                  v-else
                  type="primary"
                  shape="round"
                  @click="btItem.click"
                  style="margin-right: 5px"
                >
                  <component :is="btItem.iconRender" />
                  {{ btItem.name }}
                </a-button>
              </div>
            </div>
            <div style="float: right">
              <!-- 上传任务 -->
              <div style="display: inline-block">
                <Popover placement="bottomRight" trigger="click">
                  <template #content>
                    <div v-if="UploadQueue.length > 0" class="task__content" style="width: 500px">
                      <a-list>
                        <template v-for="item in UploadQueue" :key="item.uploadId">
                          <a-list-item class="list">
                            <a-list-item-meta>
                              <template #title>
                                <span>{{ item.filename }}</span>
                              </template>
                              <template #description>
                                <div>
                                  <div style="display: inline-block" v-if="item.status === 0"
                                    >上传准备中...</div
                                  >
                                  <div style="display: inline-block" v-else-if="item.status === 1"
                                    >上传中...</div
                                  >
                                  <div style="display: inline-block" v-else-if="item.status === 2"
                                    >暂停中...</div
                                  >
                                  <div style="display: inline-block" v-else-if="item.status === 3"
                                    >合并文件中...</div
                                  >
                                  <div style="display: inline-block" v-else-if="item.status === 4"
                                    >上传完成</div
                                  >
                                  <div style="display: inline-block" v-else-if="item.status === 9"
                                    >上传中止</div
                                  >
                                  <div
                                    class="iconBtn"
                                    style="color: rgb(196, 76, 21)"
                                    v-if="item.status === 1 || item.status === 2"
                                    ><CloseCircleOutlined
                                      @click="
                                        () => {
                                          item.status = 9;
                                        }
                                      "
                                    />
                                  </div>
                                  <div
                                    v-if="item.status === 1"
                                    class="iconBtn"
                                    style="color: rgb(8, 95, 153)"
                                    ><PauseCircleOutlined
                                      @click="
                                        () => {
                                          item.status = 2;
                                        }
                                      "
                                    />
                                  </div>
                                  <div
                                    v-if="item.status === 2"
                                    class="iconBtn"
                                    style="color: rgb(8, 95, 153)"
                                  >
                                    <PlayCircleOutlined
                                      @click="
                                        () => {
                                          item.status = 1;
                                        }
                                      "
                                    />
                                  </div>
                                </div>
                                <div>
                                  <Progress :percent="item.progress.toFixed(2)" status="active" />
                                </div>
                              </template>
                            </a-list-item-meta>
                          </a-list-item>
                        </template>
                      </a-list>
                    </div>
                    <p v-else>暂无上传任务</p>
                  </template>
                  <Badge :dot="hasTaskRun(UploadQueue)">
                    <a-button type="text" size="middle" class="upload_type">
                      <VerticalAlignTopOutlined class="upload_icon_type" />
                    </a-button>
                  </Badge>
                </Popover>
              </div>
              <!-- 搜索按钮 -->
              <a-input-search
                v-model:value="value"
                placeholder="搜索我的文件"
                style="width: 300px; margin-left: 20px"
                @search="getData"
              />
            </div>
            <div>
              <Divider style="margin-top: 15px; margin-bottom: 5px" />
            </div>
            <!-- 面包屑 -->
            <div style="float: left,padding-top:6px">
              <CustomBreadcrumb ref="breadRef" :routes="bread" @refresh="changeFolderId" />
            </div>
          </div>
          <div>
            <Divider style="margin-top: 42px; margin-bottom: 5px" />
          </div>
          <!-- 文件夹、文件列表 -->
          <div class="content-div">
            <a-list
              :grid="{ gutter: 8, xs: 4, sm: 5, md: 7, lg: 9, xl: 11, xxl: 11 }"
              :data-source="data"
            >
              <template #renderItem="{ item }">
                <a-list-item>
                  <a-card
                    v-if="item.fileType == 0"
                    @contextmenu.stop="folderHandleContext(item, 1, $event)"
                    @click="selectFileFolder(item, 1, $event)"
                    :class="
                      item.fileType + '&' + item.id === selected
                        ? 'ant-card-bordered-selected select-disabled'
                        : 'select-disabled'
                    "
                    @dblclick="fileDblclick(item)"
                  >
                    <div
                      style="
                        text-align: center;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                      "
                    >
                      <img
                        :src="PicList[item.fileType]"
                        style="height: auto; width: auto; max-height: 80px"
                      />
                    </div>
                    <div
                      class="pictext"
                      :title="item.fileName"
                      @mousedown.stop="selectFileFolder(item, 2, $event)"
                    >
                      <a-input
                        :ref="getInputRefs"
                        v-if="item.fileType + '&' + item.id === editFlag"
                        v-model:value="item.fileName"
                        style="font-size: 12px"
                        @keydown="inputPressEnter"
                        @dblclick.stop=""
                        @mousedown.stop=""
                      />
                      <p v-else>{{ item.fileName }}</p>
                    </div>
                  </a-card>
                  <a-card
                    v-else
                    :class="
                      item.fileType + '&' + item.id === selected
                        ? 'ant-card-bordered-selected select-disabled'
                        : 'select-disabled'
                    "
                    @contextmenu.stop="fileHandleContext(item, 1, $event)"
                    @click="selectFileFolder(item, 1, $event)"
                    @dblclick="fileDblclick(item)"
                  >
                    <div
                      style="
                        text-align: center;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                      "
                    >
                      <img
                        :src="PicList[checkSuffix(item.fileName)]"
                        style="height: auto; width: auto; max-height: 80px"
                      />
                    </div>
                    <div
                      class="pictext"
                      :title="item.fileName"
                      @mousedown.stop="selectFileFolder(item, 2, $event)"
                    >
                      <a-input
                        :ref="getInputRefs"
                        selection-start="1"
                        selection-end="3"
                        v-if="item.fileType + '&' + item.id === editFlag"
                        v-model:value="item.fileName"
                        style="font-size: 12px"
                        @keydown="inputPressEnter"
                        @dblclick.stop=""
                        @mousedown.stop=""
                      />
                      <p v-else>{{ item.fileName }}</p>
                    </div>
                  </a-card>
                </a-list-item>
              </template>
            </a-list>
          </div>
        </div>
      </div>
    </div>
  </div>
  <PreviewModal @register="registerModal" />
</template>
<script lang="ts">
  import {
    EllipsisOutlined,
    FileOutlined,
    VideoCameraOutlined,
    ClockCircleOutlined,
    PictureOutlined,
    CustomerServiceOutlined,
    UploadOutlined,
    SearchOutlined,
    FolderAddOutlined,
    VerticalAlignTopOutlined,
    PlayCircleOutlined,
    PauseCircleOutlined,
    CloseCircleOutlined,
  } from '@ant-design/icons-vue';
  import {
    Tabs,
    Image,
    Button,
    Divider,
    Input,
    Upload,
    Avatar,
    Badge,
    Popover,
    Progress,
  } from 'ant-design-vue';
  import PreviewModal from './previewModal.vue';
  import { defineComponent, ref, h } from 'vue';
  import { useModal } from '/@/components/Modal';
  import CustomBreadcrumb from './Breadcrumb.vue';
  import { useContextMenu } from '/@/hooks/web/useContextMenu';
  import {
    listApi,
    createFolderApi,
    updateFolderApi,
    deleteFolderApi,
    updateFileApi,
    deleteFileApi,
    getFolderTreeApi,
    createTaskApi,
    initUploadApi,
    minioUploadApi,
    mergeFileApi,
    downloadApi,
  } from '/@/api/business/file';
  import SparkMD5 from 'spark-md5';
  import { useMessage } from '/@/hooks/web/useMessage';

  export default defineComponent({
    components: {
      Image,
      Button,
      Tabs,
      Upload,
      Popover,
      Progress,
      TabPane: Tabs.TabPane,
      CustomBreadcrumb,
      Divider,
      Input,
      FileOutlined,
      SearchOutlined,
      EllipsisOutlined,
      VideoCameraOutlined,
      ClockCircleOutlined,
      PictureOutlined,
      CustomerServiceOutlined,
      UploadOutlined,
      FolderAddOutlined,
      VerticalAlignTopOutlined,
      Badge,
      Avatar,
      PlayCircleOutlined,
      PauseCircleOutlined,
      CloseCircleOutlined,
      PreviewModal,
    },
    setup() {
      const [registerModal, { openModal }] = useModal();
      const visible = ref<boolean>(false);

      const hide = () => {
        visible.value = false;
      };

      const { notification } = useMessage();
      //上传队列
      const UploadQueue = ref([]);
      //文件列表
      const PicList = [
        '/resource/img/filetype/folder.png',
        '/resource/img/filetype/image.png',
        '/resource/img/filetype/media.png',
        '/resource/img/filetype/file.png',
        '/resource/img/filetype/music.png',
        '/resource/img/filetype/bt.png',
        '/resource/img/filetype/other.png',
      ];
      const inputRefs = ref(null);
      //遍历获取元素，然后放在一个数组里
      function getInputRefs(el) {
        if (el) {
          inputRefs.value = el;
        }
      }

      const breadRef = ref([]);
      const bread = ref([]);
      const selectedItem = ref(null);
      const selected = ref(null);
      const editFlag = ref(null);
      const value = ref<string>('');
      const data = ref([]);
      const folderId = ref<number>(null);
      const activeKey = ref('');

      //判断文件的类型
      //文本类型
      const picType = [
        'BMP',
        'DIB',
        'PCP',
        'DIF',
        'WMF',
        'GIF',
        'MPT',
        'TIF',
        'EPS',
        'PSD',
        'CDR',
        'IFF',
        'TGA',
        'PCD',
        'PNG',
        'JPG',
        'JPEG',
      ];
      const mediaType = ['AVI', 'WMV', 'MPG', 'MPEG', 'MOV', 'RM', 'RAM', 'SWF', 'FLV', 'MP4'];
      const txtType = ['TXT', 'DOC', 'DOCX', 'XLS', 'XLSX', 'PPT', 'PPTX', 'WPS', 'DPS', 'ET'];
      const musicType = ['WAV', 'MIDI', 'CDA', 'MP3', 'WMA', 'APE', 'RAM', 'FLAC'];
      const btType = ['TORRENT'];
      const checkSuffix = (item) => {
        const suffix = item.substring(item.lastIndexOf('.') + 1, item.length);
        if (picType.findIndex((item) => item == suffix.toUpperCase()) >= 0) {
          return 1;
        } else if (mediaType.findIndex((item) => item == suffix.toUpperCase()) >= 0) {
          return 2;
        } else if (txtType.findIndex((item) => item == suffix.toUpperCase()) >= 0) {
          return 3;
        } else if (musicType.findIndex((item) => item == suffix.toUpperCase()) >= 0) {
          return 4;
        } else if (btType.findIndex((item) => item == suffix.toUpperCase()) >= 0) {
          return 5;
        } else {
          return 6;
        }
      };
      const getData = async () => {
        //左侧Tab 面包屑与文件夹层级区分
        if (activeKey.value && activeKey.value !== '') {
          //清除面包屑
          folderId.value = null;
          achieveList.forEach((e) => {
            if (e.key === activeKey.value) {
              setBreadDirectely(e.name);
            }
          });
        } else {
          getBread();
        }

        breadRef.value.refreshBread(bread.value);
        const cond = {
          fileName: value.value,
          folderId: folderId.value,
          fileType: activeKey.value,
        };
        //文件列表获取
        const listValue = await listApi(cond);
        //再加上原文件名
        listValue.forEach((element) => {
          element.oldFildName = element.fileName;
        });
        data.value = listValue;
      };

      //获取面包屑
      async function getBread() {
        //面包屑获取
        const data = {
          id: folderId.value,
        };
        const breads = await getFolderTreeApi(data);

        bread.value = [];
        breads.forEach((e) => {
          const tmp = {
            id: e.id || 'base',
            folder: e.folder || '我的文件',
          };
          bread.value.push(tmp);
        });
        breadRef.value.refreshBread(bread.value);
      }

      //点击tab切换类型时直接定义面包屑
      async function setBreadDirectely(e) {
        bread.value = [];
        const tmp = [
          {
            id: 'base',
            folder: '我的文件',
          },
          {
            id: 'tab',
            folder: e,
          },
        ];

        bread.value = tmp;
        breadRef.value.refreshBread(bread.value);
      }

      // 右键菜单
      const [createContextMenu] = useContextMenu();
      //左侧选项栏
      const achieveList: [] = [
        {
          key: '',
          name: '全部文件',
          bold: true,
        },
        {
          key: '-1',
          name: '最近',
          iconRender: 'ClockCircleOutlined',
        },
        {
          key: '1',
          name: '图片',
          iconRender: 'PictureOutlined',
        },
        {
          key: '2',
          name: '视频',
          iconRender: 'VideoCameraOutlined',
        },
        {
          key: '3',
          name: '文档',
          iconRender: 'FileOutlined',
        },
        {
          key: '4',
          name: '音乐',
          iconRender: 'CustomerServiceOutlined',
        },
        {
          key: '5',
          name: '种子',
          iconRender: () => {
            const text = 'Bt';
            return h(Button, { type: 'link' }, text);
          },
        },
        {
          key: '6',
          name: '其他',
          iconRender: 'EllipsisOutlined',
        },
      ];
      //按钮组
      const buttonList: [] = [
        {
          key: '0',
          name: '上传',
          iconRender: 'UploadOutlined',
        },
        {
          key: '1',
          name: '创建文件夹',
          iconRender: 'FolderAddOutlined',
          click: () => createFolder(),
        },
      ];
      //右键菜单
      function fileHandleContext(item, type, e: MouseEvent) {
        //先触发框框选中事件
        selectFileFolder(item, type);
        createContextMenu({
          event: e,
          styles: {
            border: '1px solid rgb(230, 230, 230)',
            backgroundColor: 'rgb(252, 253, 253)',
          },
          items: [
            {
              label: '预览',
              icon: 'icon-park-outline:preview-open',
              handler: async () => {
                if (checkSuffix(selectedItem.value.fileName) === 6) {
                  notification.error({
                    description: '文件 ' + selectedItem.value.fileName + ' 暂不支持预览...',
                    duration: 3,
                  });
                } else {
                  openModal(true, {
                    id: selectedItem.value.id,
                    type: checkSuffix(selectedItem.value.fileName),
                    fileName: selectedItem.value.fileName,
                  });
                }
              },
            },
            {
              label: '下载',
              icon: 'bi:cloud-download',
              handler: () => {
                const downres = downloadApi(selectedItem.value.id);
                downres.then((url) => {
                  notification.success({
                    description: '文件 ' + selectedItem.value.fileName + ' 下载中...',
                    duration: 3,
                  });
                  download(url, selectedItem.value.fileName);
                });
              },
            },
            {
              label: '重命名',
              icon: 'akar-icons:edit',
              handler: () => {
                selectFileFolder(selectedItem.value, 2, 'handle');
              },
            },
            {
              label: '删除',
              icon: 'fluent:delete-20-regular',
              handler: () => {
                deleteFile();
              },
            },
          ],
        });
      }
      /**
       * 获取 blob
       * @param  {String} url 目标文件地址
       * @return {cb}
       */
      function getBlob(url, cb) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.responseType = 'blob';
        xhr.onload = function () {
          if (xhr.status === 200) {
            cb(xhr.response);
          }
        };
        xhr.send();
      }

      /**
       * 保存
       * @param  {Blob} blob
       * @param  {String} filename 想要保存的文件名称
       */
      function saveAs(blob, filename) {
        if (window.navigator.msSaveOrOpenBlob) {
          navigator.msSaveBlob(blob, filename);
        } else {
          var link = document.createElement('a');
          var body = document.querySelector('body');

          link.href = window.URL.createObjectURL(blob);
          link.download = filename;

          // fix Firefox
          link.style.display = 'none';
          body.appendChild(link);

          link.click();
          body.removeChild(link);

          window.URL.revokeObjectURL(link.href);
        }
      }

      /**
       * 下载
       * @param  {String} url 目标文件地址
       * @param  {String} filename 想要保存的文件名称
       */
      function download(url, filename) {
        getBlob(url, function (blob) {
          saveAs(blob, filename);
          notification.success({
            description: '文件 ' + filename + ' 下载完成',
            duration: 3,
          });
        });
      }

      //文件夹右键菜单
      function folderHandleContext(item, type, e: MouseEvent) {
        //先触发框框选中事件
        selectFileFolder(item, type);
        createContextMenu({
          event: e,
          styles: {
            border: '1px solid rgb(230, 230, 230)',
            backgroundColor: 'rgb(252, 253, 253)',
          },
          items: [
            {
              label: '重命名',
              icon: 'akar-icons:edit',
              handler: () => {
                selectFileFolder(selectedItem.value, 2, 'handle');
              },
            },
            {
              label: '删除',
              icon: 'fluent:delete-24-regular',
              handler: () => {
                deleteFolder();
              },
            },
          ],
        });
      }
      //文件夹右键菜单
      function backgroudHandleContext(e: MouseEvent) {
        createContextMenu({
          event: e,
          styles: {
            border: '1px solid rgb(230, 230, 230)',
            backgroundColor: 'rgb(252, 253, 253)',
          },
          items: [
            {
              label: '创建文件夹',
              icon: 'akar-icons:edit',
              handler: () => {
                createFolder();
              },
            },
          ],
        });
      }

      // file 对象
      const chunkSize = 5 * 1024 * 1024; // 切片大小为5M

      //获取文件的MD5信息 分片获取
      const ReadFileMD5 = (param) => {
        return new Promise((resolve, reject) => {
          const file = param.file;
          const fileReader = new FileReader();
          const md5 = new SparkMD5();
          let index = 0;
          const loadFile = () => {
            const slice = file.slice(index, index + chunkSize);
            fileReader.readAsBinaryString(slice);
          };
          loadFile();
          fileReader.onload = (e) => {
            md5.appendBinary(e.target.result);
            if (index < file.size) {
              index += chunkSize;
              loadFile();
            } else {
              // md5.end() 就是文件md5码
              var md5Str = md5.end();
              return resolve(md5Str);
            }
          };
          fileReader.onerror = () => {
            reject('文件解析失败');
          };
        });
      };

      const updateTasks = (uploadId, progress, status) => {
        for (let i = 0; i < UploadQueue.value.length; i++) {
          const item = UploadQueue.value[i];
          if (item.uploadId === uploadId) {
            if (progress !== undefined) {
              item.progress = progress;
            }
            if (status !== undefined) {
              item.status = status;
            }
            return;
          }
        }
      };

      const getTask = (uploadId) => {
        for (let i = 0; i < UploadQueue.value.length; i++) {
          const item = UploadQueue.value[i];
          if (item.uploadId === uploadId) {
            return item;
          }
        }
      };

      const delay = (times) => {
        return new Promise(async function (resolve) {
          async function doDelay() {
            resolve(1);
          }
          setTimeout(function () {
            doDelay();
          }, times);
        });
      };
      /**
       * 选择文件进行上传
       * 在这里只校验一下文件正确性 并在数据库创建上传任务
       */
      const customRequest = async (file) => {
        const taskId = guid();
        //初始化任务状态
        const queueItem = {
          filename: file.file.name,
          progress: 0,
          //0初始化中 1上传中 2暂停中 3整理文件中 4上传完成 9 上传中止
          status: 0,
          uploadId: taskId,
        };
        UploadQueue.value.unshift(queueItem);
        //上传开始
        let chunks = Math.ceil(file.file.size / chunkSize);
        //获取文件的MD5并进行下一步操作
        ReadFileMD5(file).then((res) => {
          const md5 = res;
          //根据MD5创建任务
          const data = {
            folderId: folderId.value,
            md5: md5 + '.' + file.file.name.substring(file.file.name.lastIndexOf('.') + 1),
            fileName: file.file.name,
            type: 1, //上传
          };

          const createTask = createTaskApi(data);
          createTask
            .then(async (tid) => {
              //任务创建成功
              notification.success({
                description: '文件 ' + file.file.name + ' 上传中...',
                duration: 3,
              });
              //创建初始化任务
              const initData = {
                objectName:
                  md5 + '.' + file.file.name.substring(file.file.name.lastIndexOf('.') + 1),
                partCount: chunks,
              };

              const ress = await initUploadApi(initData);

              if (!ress.finished) {
                updateTasks(taskId, undefined, 1);
                //上传操作
                let index = 0;
                let tryTimes = 0; //重试次数最多三次
                const uploadFileChunck = async () => {
                  //判断当前任务的状态
                  if (getTask(taskId).status === 1) {
                    const url = ress.uploadUrl[index];
                    const slice = file.file.slice(index * chunkSize, (index + 1) * chunkSize);
                    const uplRes = minioUploadApi(url, slice);
                    uplRes
                      .then(async () => {
                        index++;
                        //正常上传中
                        updateTasks(taskId, (100 * index) / chunks, undefined);
                        tryTimes = 0;
                        if (index < chunks) {
                          uploadFileChunck();
                        } else if (index === chunks) {
                          //整理中
                          updateTasks(taskId, 100, 3);
                          const mergeData = {
                            tid: tid,
                            md5:
                              md5 +
                              '.' +
                              file.file.name.substring(file.file.name.lastIndexOf('.') + 1),
                            uploadId: ress.uploadId,
                            chuncks: chunks,
                            finished: false,
                          };
                          await mergeFileApi(mergeData);
                          //上传完成
                          notification.success({
                            description: '文件 ' + file.file.name + ' 上传完成',
                            duration: 3,
                          });
                          //合并成功
                          updateTasks(taskId, 100, 4);
                          getData();
                        }
                      })
                      .catch(() => {
                        //任务创建成功
                        if (tryTimes < 3) {
                          tryTimes++;
                          uploadFileChunck();
                        } else {
                          notification.success({
                            description: '文件 ' + file.file.name + ' 上传失败,请重试...',
                            duration: 3,
                          });
                          updateTasks(taskId, undefined, 9);
                        }
                      });
                  } else if (getTask(taskId).status === 9) {
                    return;
                  } else {
                    await delay(1000);
                    uploadFileChunck();
                  }
                };
                await uploadFileChunck();
              } else {
                updateTasks(taskId, 100, 3);
                //上传完成后触发文件合并工作
                //上传结束后进行合并
                const mergeData = {
                  tid: tid,
                  md5: md5 + '.' + file.file.name.substring(file.file.name.lastIndexOf('.') + 1),
                  uploadId: ress.uploadId,
                  chuncks: chunks,
                  finished: true,
                };
                await mergeFileApi(mergeData);
                //上传完成
                notification.success({
                  description: '文件 ' + file.file.name + ' 上传完成',
                  duration: 3,
                });
                //合并成功
                updateTasks(taskId, 100, 4);
              }
              getData();
            })
            .catch(() => {
              updateTasks(taskId, undefined, 9);
            });
        });
      };
      //
      const hasTaskRun = (item) => {
        for (let i = 0; i < item.length; i++) {
          if (item[i].status === 0 || item[i].status === 1 || item[i].status === 2) {
            return true;
          }
        }

        return false;
      };
      //
      function handleSuccess() {
        getData();
      }
      //创建文件夹
      function createFolder() {
        //创建文件夹
        const dataValue = data.value;
        const newItem = {
          fileName: '新建文件夹',
          folderId: folderId.value,
          fileType: 0,
          id: 'create' + guid(),
        };
        dataValue.unshift(newItem);
        data.value = dataValue;
        selectFileFolder(newItem, 1, 'handle');
        selectFileFolder(newItem, 2, 'handle');
      }
      //删除文件夹
      async function deleteFolder() {
        //删除文件夹
        const data = {
          id: selectedItem.value.id,
        };
        await deleteFolderApi(data);
        getData();
      }
      //删除文件
      async function deleteFile() {
        //删除文件夹
        const data = {
          id: selectedItem.value.id,
        };
        await deleteFileApi(data);
        getData();
      }
      //修改文件、文件夹名称
      async function changeFileFolder(item) {
        if (item !== undefined && item !== null && item.fileName !== item.oldFildName) {
          //修改文件夹还是修改文件
          if (item.fileType === 0) {
            setTimeout(async () => {
              //初始化信息
              const data = {
                parentFolderId: folderId.value,
                folder: item.fileName,
              };
              try {
                //判断ID是不是临时ID，是的话表示新建
                const reg = new RegExp(/^[0-9]*$/);
                if (reg.test(item.id)) {
                  //是数字 更新
                  data.id = item.id;
                  await updateFolderApi(data);
                } else {
                  await createFolderApi(data);
                }
              } finally {
                //刷新文件列表
                getData();
              }
            }, 200);
          } else {
            setTimeout(async () => {
              //初始化信息
              const data = {
                folderId: folderId.value,
                fileName: item.fileName,
                id: item.id,
              };
              try {
                await updateFileApi(data);
              } finally {
                //刷新文件列表
                getData();
              }
            }, 200);
          }
        }
      }
      //清除选中及修改状态
      async function clearEdit() {
        //触发修改事件
        const sds = inputPressEnterPromise();
        sds.then(() => {
          selected.value = null;
          selectedItem.value = null;
        });
      }
      //清除选中及修改状态
      async function inputPressEnter(e) {
        if (e.key === 'Enter') {
          clearEdit();
        }
      }
      //清除选中及修改状态
      async function inputPressEnterPromise() {
        return new Promise(async (resolve) => {
          //触发修改事件
          if (editFlag.value !== null) {
            editFlag.value = null;
            await changeFileFolder(selectedItem.value);
            return resolve();
          } else {
            return resolve();
          }
        });
      }
      //文件双击事件
      async function fileDblclick(item) {
        if (item.fileType === 0) {
          folderId.value = item.id;
          getBread();
          await getData();
        }
      }
      //选择文件
      function selectFileFolder(item, type, event) {
        //点击图片选中
        if (item.fileType + '&' + item.id === selected.value) {
          //鼠标左键触发修改
          if (2 === type && event && (event.button === 0 || event === 'handle')) {
            editFlag.value = item.fileType + '&' + item.id;
            setTimeout(() => {
              inputRefs.value.select();
              if (item.fileType !== 0) {
                //非文件夹只选中文件名部分
                inputRefs.value.setSelectionRange(0, item.fileName.lastIndexOf('.'));
              }
            }, 100);
          }
        } else {
          selectedItem.value = item;
          selected.value = item.fileType + '&' + item.id;
          editFlag.value = null;
        }
      }
      //子组件的赋值
      async function changeFolderId(fid) {
        if (fid === 'base') {
          folderId.value = null;
        } else {
          folderId.value = fid;
        }

        await getData();
      }
      //guid生成
      function guid() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
          var r = (Math.random() * 16) | 0,
            v = c == 'x' ? r : (r & 0x3) | 0x8;
          return v.toString(16);
        });
      }

      return {
        bread,
        breadRef,
        getInputRefs,
        selected,
        editFlag,
        value,
        activeKey,
        data,
        getData,
        PicList,
        achieveList,
        buttonList,
        createFolder,
        customRequest,
        clearEdit,
        fileDblclick,
        fileHandleContext,
        folderHandleContext,
        backgroudHandleContext,
        handleSuccess,
        selectFileFolder,
        inputPressEnter,
        changeFolderId,
        UploadQueue,
        hide,
        hasTaskRun,
        checkSuffix,
        registerModal,
      };
    },
    mounted() {
      this.getData();
    },
  });
</script>
<style lang="less" scoped>
  .select-disabled {
    -webkit-user-select: none;

    -moz-user-select: none;

    -ms-user-select: none;

    user-select: none;
  }
  .tab-header {
    padding-bottom: 25%;
    background: white;
    padding-left: 1%;
    padding-right: 1%;
    padding-top: 0%;
  }
  .content {
    display: flex;
    &__ {
      &left {
        width: 125px;
        flex-shrink: 0;
      }
      &right {
        flex: 1;
      }
    }

    .task__content {
      width: 600px;
      padding: 24px;
      margin-top: 12px;
      margin-right: 80px;
      background-color: @component-background;
      .list {
        position: relative;
      }
      .description {
        display: inline-block;
        width: 40%;
      }
    }
  }
  ::v-deep(.ant-progress-outer) {
    width: 96%;
  }
  .iconBtn {
    float: right;
    margin-left: 5px;
    font-size: 18px;
  }
  .ant-card-bordered {
    border: 1px solid transparent;
    border-radius: 3px;
    :hover {
      background-color: rgb(218, 244, 252);
    }
  }
  .ant-card-bordered-selected {
    border: 1px solid rgba(75, 209, 243, 0.897);
    background-color: rgba(190, 242, 255, 0.76);
    :hover {
      background-color: rgba(190, 242, 255, 0.76);
    }
    .ant-input {
      background-color: white;
      :hover {
        background-color: white;
      }
    }
  }
  .pictext {
    margin-top: 10px;
    text-align: center;
    font-weight: 500;
    font-size: 12px;
    text-overflow: -o-ellipsis-lastline;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }
  ::v-deep(.ant-card-body) {
    padding: 1px !important;
  }
  ::v-deep(.ant-input-search) {
    .ant-input {
      border-radius: 14px 0 0 14px !important;
      background: rgb(241, 241, 241);
    }
    .ant-input-group {
      .ant-input-search-button {
        border-radius: 0 14px 14px 0 !important;
        background: rgb(241, 241, 241);
      }
    }
  }
  ::v-deep(.content-div) {
    .ant-input {
      padding: 1px !important;
      margin-bottom: 0.7em;
      border-radius: 4px;
    }
  }
  .upload_type {
    padding: 0px 0px !important;
    .upload_icon_type {
      font-size: 18px;
      color: rgb(75, 139, 221);
      :hover {
        color: rgb(8, 95, 153);
      }
    }
  }
</style>
